package com.token.base;
import java.net.URLDecoder;
import java.text.DecimalFormat;
import java.util.Vector;

import lotus.domino.Session;
import lotus.domino.Agent;
import lotus.domino.Database;
import lotus.domino.Document;
import lotus.domino.NotesException;


/**
 * 操作类，继承BaseUtil类
 * @author chenjianxiong 2020/2/15
 */
public class FuncUtil extends BaseUtil {
    private Session session = null;
    private Database db = null;
    private Document doc = null;
    private String dbPath = null;
    private int index = 0;
    private StringBuilder postStr = null;
    private boolean isPost = false;

    /**
     * 构造函数，调用父类。
     * @param session 会话对象
     * @throws Exception 错误信息
     */
    public FuncUtil(Session session) throws Exception {
        super();
        this.session = session;
        this.db = session.getCurrentDatabase();
        this.doc = session.getAgentContext().getDocumentContext();
    }

    public FuncUtil() throws Exception {
        super();
    }
    /**
     * 获取当前会话对象
     * @return Session
     */
    public Session getSession() {
        return session;
    }

    /**
     * 设置当前数据库目录。
     * @param path 目录名
     */
    public void setCurPath(String path) {
        dbPath = path;
    }

    /**
     * 获取当前的数据库
     * @return Database
     */
    public Database getCurDb() {
        return this.db;
    }

    /**
     * 获取当前的文档
     * @return Document
     */
    public Document getCurDoc() {
        return this.doc;
    }

    /**
     * 是否是Post
     * @return boolean
     */
    public boolean isPost() {
        return isPost;
    }

    /**
     * 获取post数据
     * @return String
     * @throws NotesException 错误信息
     */
    public String getPostContent() throws NotesException {
        if (this.postStr == null) {
            return doc.getItemValueString("Request_Content");
        } else {
            return this.postStr.toString();
        }
    }

    /**
     * 处理请求超多内容时，REQUEST_CONTENT域拆分多个时，把字符合并。
     * @throws Exception 错误信息
     */
    private void requestContent() throws Exception {
        DecimalFormat df = new DecimalFormat("000");
        String o = "REQUEST_CONTENT_" + df.format(index);
        if (doc.hasItem(o)) {
            postStr.append(doc.getItemValueString(o));
            index++;
            requestContent();
        }
    }

    /**
     * 获取数字
     * @param keyName url key
     * @return 数字
     */
    public int getUrlQueryInteger(String keyName){
        return Integer.parseInt(this.getUrlQueryString(keyName));
    }

    /**
     * 获取数字
     * @param keyName url key
     * @return 数字
     */
    public long getUrlQueryLong(String keyName){
        return Long.parseLong(this.getUrlQueryString(keyName));
    }

    /**
     * 获取数字
     * @param keyName url key
     * @return 数字
     */
    public double getUrlQueryDouble(String keyName){
        return Double.parseDouble(this.getUrlQueryString(keyName));
    }

    /**
     * 获取指定数据库对象的目录名。
     * @param db 数据库对象
     * @return String
     */
    public String getDbPath(Database db) {
        try {
            return db.getFilePath().substring(0, db.getFilePath().length() - (db.getFileName().length() + 1));
        } catch (NotesException e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 获取当前数据库对象的目录名。
     * @return String
     * @throws NotesException 错误信息
     */
    public String getCurDbPath() throws NotesException {
        return this.getDbPath(db);
    }

    /**
     * 获取服务器名
     * @return String
     * @throws NotesException 错误信息
     */
    public String getServerName() throws NotesException {
        return db.getServer();
    }

    /**
     * 输出当前请求是 POST或GET，只用于ajax
     * @return String
     */
    public String getRequestMethod() {
        try {
            return doc.getItemValueString("REQUEST_METHOD").toUpperCase();
        } catch (NotesException e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 返回当前数据库名称。
     * @return String
     */
    public String getCurDbFileName() {
        try {
            return this.db.getFileName();
        } catch (NotesException e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 获取当前的_path目录
     * @return String
     */
    public String getCurPath() {
        if (dbPath == null) {
            this.setPath();
        }
        return dbPath;
    }

    /**
     * 设置当前目录
     */
    private void setPath() {
        String path = this.getUrlQueryString("_path");
        if (path != null && !"".equals(path)) {
            dbPath = path;
        } else {
            dbPath = this.getDbPath(db);
        }
    }

    @Override
    protected String[][] initQueryValue() {
        try {
            if (doc == null) {
                return null;
            }
            String method = doc.getItemValueString("REQUEST_METHOD");
            String post = "POST";
            String get = "GET";
            String stringNameGet = "Query_String_Decoded";
            String stringNamePost = "Request_Content";
            if (post.equalsIgnoreCase(method)) {
                isPost = true;
                //存在Request_Content域，读取值。
                if (doc.hasItem(stringNamePost)) {
                    return splitQueryString(doc.getItemValueString(stringNamePost));
                } else {
                    //不存在，则检查是否有Request_Content_000 .. n 域
                    postStr = new StringBuilder(2000);
                    requestContent();
                    return splitQueryString(postStr.toString());
                }
            } else if (method.equals(get)) {
                isPost = false;
                return splitQueryString(doc.getItemValueString(stringNameGet));
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 按&amp;分割字符串
     * @param queryStr URL a=1&amp;b=2
     * @return StringArray
     * @throws Exception 错误
     */
    public String[][] splitQueryString(String queryStr) throws Exception {
        String[][] queryArr;
        String[] qy = queryStr.split("&");
        int length = qy.length;
        //必须加判断，否则报空指针的错误。
        if ("".equals(qy[0])) {
            queryArr = new String[2][1];
            queryArr[0][0] = "";
            queryArr[1][0] = "";
        } else {
            queryArr = new String[2][length];
            int num;
            for (int i = 0; i < length; i++) {
                String qs = qy[i];
                num = qs.indexOf("=");
                if(num > 0) {
                    queryArr[0][i] = qs.substring(0, num);
                    queryArr[1][i] = URLDecoder.decode(qs.substring(num + 1), "UTF-8");
                }else{
                    queryArr[0][i] = "";
                    queryArr[1][i] = "";
                }
            }
        }
        return queryArr;
    }
    /**
     * 代理调用代理获取文档
     * @throws NotesException 错误信息
     * @return Document
     */
    public Document getDocumentByAgentId() throws NotesException{
        Agent agent = this.session.getAgentContext().getCurrentAgent();
        return db.getDocumentByID(agent.getParameterDocID());
    }
    /**
     * 获取用户信息
     * @return String
     */
    public String getEffectiveUserName(){
        try{
            return session.getEffectiveUserName();
        }catch(NotesException e){
            return "";
        }
    }
    /**
     * 获取用户工号
     * @return String
     */
    public String getCurPersonNumber(){
        try{
            String tmp = session.getEffectiveUserName();
            return tmp.substring(3,tmp.indexOf("/"));
        }catch(NotesException e){
            return "";
        }
    }
    /**
     * 打开数据库
     * @param dbName  数据库名称
     * @param isCurPath false dbname 要传带目录的数据库名称
     * @return Database
     * @throws NotesException 错误信息
     */
    public Database openDb(String dbName,boolean isCurPath) throws NotesException{
        String path;
        if(isCurPath){
            path = getCurPath() + "/";
        }else{
            path = "";
        }
        return session.getDatabase(getServerName(),path + dbName,false);
    }

    /**
     * 打开当前db目录下的数据库
     * @param dbName  数据库名称，不含目录名
     * @return Database
     * @throws NotesException 错误信息
     */
    public Database openDb(String dbName) throws NotesException{
        return this.openDb(dbName,true);
    }


    protected void printAgentName(){
        try {
            if (doc != null) {
                System.out.println("出错地址：[" + doc.getItemValueString("PATH_INFO") + "]");
            }
        }catch (Exception e){

        }
    }
    /**
     * 获取人员群组列表
     * @return StringBuffer
     * @throws NotesException 错误信息
     */
    public StringBuffer getUserGroupNameList() throws NotesException{
        Vector<?> vector = session.getUserGroupNameList();
        StringBuffer powerid = new StringBuffer();
        boolean b = true;
        for(int i=0;i<vector.size();i++){
            if(vector.get(i).toString().contains("*")){
                powerid.append(b? "'" + vector.get(i) + "'":",'" + vector.get(i) + "'");
                b = false;
            }
        }
        return powerid;
    }
    /**
     * 释放Domino对象
     */
    @Override
    public void recycle() {
        try {
            if (doc != null) {
                doc.recycle();
            }
            if (db != null) {
                db.recycle();
            }
            if (session != null) {
                session.recycle();
            }
            System.gc();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
